<?php

namespace CommonBundle\Controller\System;

use CommonBundle\Controller\RestController;
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\ORM\Mapping\ManyToMany;
use Doctrine\ORM\Mapping\ManyToOne;
use Doctrine\ORM\Mapping\OneToOne;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Swagger\Annotations as SWG;
use Symfony\Component\HttpFoundation\Response;

/**
 * @Route("/system/entities", name="system-entity-")
 */
class EntityController extends RestController
{
    /**
     * Export all entities
     *
     * @Route("", name="list", methods={"GET"})
     * @SWG\Response(
     *     response=200,
     *     description="Export all entities",
     * )
     * @SWG\Parameter(name="page", in="query", type="string")
     * @SWG\Parameter(name="limit", in="query", type="string")
     * @SWG\Tag(name="system")
     *
     * @return Response
     */
    public function listAction()
    {
        $entityManager = $this->getDoctrine()->getManager();
        $entities = [];
        $metadatas = $entityManager->getMetadataFactory()->getAllMetadata();
        foreach ($metadatas as $metadata) {
            $entities[] = $metadata->getName();
        }

        return $this->Success($entities);
    }

    /**
     * Retrieve an entity metadatas
     *
     * @Route("/{entityName}", name="retrieve", methods={"GET"}, requirements={"entityName": ".*"})
     * @SWG\Response(
     *     response=200,
     *     description="Retrieve an entity metadatas",
     * )
     * @SWG\Parameter(name="page", in="query", type="string")
     * @SWG\Parameter(name="limit", in="query", type="string")
     * @SWG\Tag(name="system")
     *
     * @param $entityName
     * @return Response
     * @throws \Doctrine\Common\Annotations\AnnotationException
     * @throws \ReflectionException
     */
    public function retrieveAction($entityName)
    {
        $entityName = str_replace('/', '\\', $entityName);

        // translation

        // Document reader.
        $docReader = new AnnotationReader();
        $reflect = new \ReflectionClass($entityName);

        // Get class information with reflection
        foreach ($reflect->getProperties() as $val) {
            $annotations = $docReader->getPropertyAnnotations($reflect->getProperty($val->name));
            foreach ($annotations as $annotation) {
                // Normal type
                // Note: type must be defined in Entity fields
                if(property_exists($annotation, 'type')) {
                    $entityFields[$val->name]['metadata'] = $annotation;
                }

                // Accept ManyToOne type
                elseif($annotation instanceof ManyToOne) {
                    $entityFields[$val->name]['metadata'] = [
                        'type' => 'ManyToOne',
                        'targetEntity' => $annotation->targetEntity,
                    ];
                }

                elseif($annotation instanceof OneToOne) {
                    $entityFields[$val->name]['metadata'] = [
                        'type' => 'OneToOne',
                        'targetEntity' => $annotation->targetEntity,
                    ];
                }

                elseif($annotation instanceof ManyToMany) {
                    $entityFields[$val->name]['metadata'] = [
                        'type' => 'ManyToMany',
                        'targetEntity' => $annotation->targetEntity,
                    ];
                }

                // translations
                $plantext = ucwords(implode(' ',preg_split('/(?=[A-Z])/', $val->name)));
                $word = ucfirst(strtolower($plantext));

                $entityFields[$val->name]['plantext'] = $word;
                $entityFields[$val->name]['translation'] = $this->get('translator')->trans($word);
            }
        }

        return $this->Success($entityFields);
    }
}
